var picHelp = module.exports;
var fs = require('fs');
var multiparty = require('multiparty');
var path = require('path');
var CONFIG = require('../config.js');
var https = require('https');
var http = require('http');
var imageInfo = require('imageinfo');
var url = require('url');
let qiniu = require('qiniu');
let config = require('./../config');
let uuid = require('node-uuid');
var mainPath = CONFIG.PICSMAINPATH;
let bucket = config.qiniu_cfg.bucket;

//（获取七牛上传token）
picHelp.uptoken = function (bucket) {
    var putPolicy = new qiniu.rs.PutPolicy({
        scope: bucket
    });
    var accessKey = config.qiniu_cfg.access_key;
    var secretKey = config.qiniu_cfg.secret_key;
    var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
    var uploadToken = putPolicy.uploadToken(mac);
    return uploadToken;
}

//上传图片并检验参数，带上检验参数的方法,验证不正确会返回错误并删除图片
//req 表单请求，
// checkParFunc 检验参数的方法,构造好传进来，包括检验图片参数的名字 参数格式是(par,function (err,errCode,userInfo))
// maxPic 图片最大上传限制
// cb回调
//回调出去的par，files 是存放文件的数组,userInfo是用户信息
picHelp.uploadPicsAndCheckPars = function (req, checkParFunc, maxPic, pathDir, isNeedUid, cb) {
    if (!req || !checkParFunc || !pathDir) {
        cb('服务器异常', 500);
        return;
    }
    var isNeedUid = isNeedUid;
    if (!isNeedUid) {
        isNeedUid = false;
    }
    //生成multiparty对象，并配置上传目标路径

    var form = new multiparty.Form({
        uploadDir: (mainPath + '/picTemp/')
    });
    //上传完成后处理
    form.parse(req, function (error, fields, files) {

        if (error) {
            cb(error, 400);
            return;
        }

        //参数格式转换,解析出来
        var par = {};
        for (var p in fields) {
            if (p[0]) {
                par[p] = fields[p][0];
            }
        }
        //查看图片是否超过限制
        var picNum = 0;
        par.picNames = Object.keys(files);
        var picSizeArr = [];
        for (var picKey in files) {

            if (files[picKey].length > 1) { //每个名字只能带一张图片
                delPicsWithFiles(files);
                return cb('图片参数有误', 400);
            }

            par[picKey] = files[picKey][0].path;
            picNum += files[picKey].length;
            picSizeArr.push(parseInt(files[picKey][0].size));

        }
        if (picNum > maxPic) {
            //图片超过限制，删除上传来的图片
            delPicsWithFiles(files);
            return cb('图片个数超过限制', 400);
        }
        picSizeArr.sort(function (a, b) {
            return a - b;
        }).reverse();

        if (picSizeArr[0] > 4000000) {
            delPicsWithFiles(files);
            return cb('图片过大，请重新选图！', 400);
        }

        //检验参数是否正确,包括图片命名,不正确的话去删除上传的图片，并且返回错误
        checkParFunc(par, function (err, errCode) {
            if (!err) { //验证正确，去重命名
                par.files = files;

                picHelp.renamePics(par, pathDir, isNeedUid, function (err, errCode, param) {
                    if (err) {
                        cb(err, errCode, param);
                        delPicsWithFiles(files);
                        return;
                    }

                    console.log(param);

                    //上传到七牛后保存的文件名
                    let key = uuid.v4() + param.file.substring(param.file.lastIndexOf("."));
                    //生成上传 Token
                    let token = picHelp.uptoken(bucket);
                    //要上传文件的本地路径
                    let filePath = '/mnt/mb1949' + param.file;

                    var conf = new qiniu.conf.Config();
                    conf.zone = qiniu.zone.Zone_z2;
                    var formUploader = new qiniu.form_up.FormUploader(conf);
                    var putExtra = new qiniu.form_up.PutExtra();
                    formUploader.putFile(token, key, filePath, putExtra, function (respErr, respBody, respInfo) {
                        if (respErr) {
                            return cb(respErr, 400, null);
                        }

                        if (respInfo.statusCode == 200) { //上传成功
                            return cb(null, 0, {
                                "url": config.qiniu_cfg.url + key
                            });
                        } 
                        
                        return cb('上传异常!', 400, null);
                    });
                });

                return;
            }

            //验证不正确，删除上传来的图片
            delPicsWithFiles(files);
            cb(err, errCode);
        });
    });
}

//递归创建目录 异步方法
function mkdirs(dirname, callback) {
    fs.exists(dirname, function (exists) {
        if (exists) {
            callback(null);
        } else {
            mkdirs(path.dirname(dirname), function () {
                fs.mkdir(dirname, callback);
            });
        }
    });
}

//更新图片路径
function changeDir(par, index, userPath, callback) {
    var keyArr = Object.keys(par.files);

    if (keyArr.length < 1) {
        callback(null, par);
        return;
    }
    var picObj = par.files[keyArr[index]][0];
    var uploadedPath = picObj.path;

    fs.readFile(uploadedPath, function (err, bytesRead) {
        if (err) {
            callback(err, par);
            return;
        }
        var info = imageInfo(bytesRead);
        var type;
        if (!info || !info.format) {
            type = '.jpg';
        } else {
            type = imageInfoFileType(info.format);
            if (!type) {
                callback('上传图片格式有误', par);
                return;
            }
        }
        //参数正确   更换图片路径
        var picPach = userPath + type;
        var dstPath = mainPath + picPach;
        checkDirs(dstPath, function (exits) {
            if (exits) {
                picPach = userPath + (keyArr.length + index) + type;
                dstPath = mainPath + picPach;
            }
            //重命名为真实文件名
            fs.rename(uploadedPath, dstPath, function (err) {
                if (err) {
                    callback(err, par);
                    return;
                }
                par[picObj.fieldName] = picPach;
                if (index < (keyArr.length - 1)) {
                    changeDir(par, index + 1, userPath, callback);
                } else {
                    callback(null, par);
                }
            });
        });
    });
}

//检查文件是否存在
function checkDirs(dirname, callback) {
    fs.exists(dirname, function (exists) {
        if (exists) {
            callback('存在');
        } else {
            callback(null);
        }
    });
}

//根据上传来的files表单删除图片
function delPicsWithFiles(files) {
    //图片超过限制，删除上传来的图片
    for (var key in files) {
        files[key].forEach(function (picObj) {
            var uploadedPath = picObj.path;
            fs.unlink(uploadedPath, function () {});
        });
    }
}

//给上传的图片重命名 //par：参数 picType：路径名
picHelp.renamePics = function (par, picType, isNeedUid, cb) {
    if (!par.files) {
        cb('参数有误', 400);
        return;
    }
    //构造路径
    var uid = 0;
    if (par.userInfo) {
        uid = par.userInfo.main_userInfo ? par.userInfo.main_userInfo.uid : par.userInfo.uid;
    }
    var date = new Date();
    var userPath = '/' + picType;
    userPath += '/' + date.getFullYear();
    userPath += '/' + (date.getMonth() + 1);
    userPath += '/' + date.getDate();
    if (isNeedUid == true) {
        userPath += '/' + parseInt(uid / 100);
        userPath += '/' + uid;
    }
    mkdirs((mainPath + userPath), function (err) { //创建目录
        if (err) {
            cb(err, 400);
            return;
        }

        userPath += '/' + date.getHours() + date.getMinutes() + date.getSeconds() + date.getMilliseconds();
        changeDir(par, 0, userPath, function (err, par) {

            if (err) {
                cb(err, 400, par);
                return;
            }
            cb(null, 0, par);
        });
    });
}


//根据命名好的子路径删除图片的方法  将存放在字段中的路径组成数组传进来。
picHelp.delPics = function (pics) {

    if (pics.length < 1 || !(Object.prototype.toString.call(pics) === '[object Array]')) {
        return;
    }

    //删除数组中的图片
    pics.forEach(function (pic) {
        var picUrl = mainPath + pic;
        fs.unlink(picUrl, function () {});
    });

}

//将正确的图片名字作为数组传进来，再将有的名字作为数组传进来，比对命名是否不规范
picHelp.checkPicName = function (correntPicKeys, picNames) {
    //检查图片命名是否正确
    for (var i = 0; i < picNames.length; i++) {
        if (correntPicKeys.indexOf(picNames[i]) < 0) {
            return '图片参数有误';
        }
    }
}



//检验图片是否是长宽750 或 800 的
picHelp.checkPicSizeIn750Or800 = function (imgUrl, cb) {
    picHelp.getPicSize(imgUrl, function (err, size) {
        if (err) {
            cb(false);
            return;
        }
        if (size.width == 750 && size.height == 750) {
            cb(true);
            return;
        }
        if (size.width == 800 && size.height == 800) {
            cb(true);
            return;
        }
        cb(false);
    });
}


//根据http 或 https 的url地址获取图片长宽
picHelp.getPicSize = function (imgUrl, cb) {
    var options = url.parse(imgUrl);
    if (imgUrl.indexOf('https') >= 0) {
        getPicSizeUsingHttps(options, cb);
        return;
    } else if (imgUrl.indexOf('http') >= 0) {
        getPicSizeUsingHttp(options, cb);
        return;
    }
    cb('图片地址有误');
}


function getPicSizeUsingHttp(options, cb) {
    try {
        http.get(options, function (response) {
            var chunks = [];
            response.on('data', function (chunk) {
                chunks.push(chunk);
            }).on('end', function () {
                var buffer = Buffer.concat(chunks);
                var info = imageInfo(buffer);
                var size = {
                    width: info.width,
                    height: info.height
                }
                console.log(size);
                cb(null, size);
            });
        });
    } catch (e) {
        cb(e);
        console.log(e);
        return;
    }
}

function getPicSizeUsingHttps(options, cb) {
    try {
        https.get(options, function (response) {
            var chunks = [];
            response.on('data', function (chunk) {
                chunks.push(chunk);
            }).on('end', function () {
                var buffer = Buffer.concat(chunks);
                var info = imageInfo(buffer);
                var size = {
                    width: info.width,
                    height: info.height
                }
                cb(null, size);
            });
        });
    } catch (e) {
        cb(e);
        console.log(e);
        return;
    }
}

function imageInfoFileType(type) {
    switch (type) {
        case 'PNG':
            return '.png';
        case 'JPG':
            return '.jpg';
        case 'GIF':
            return '.gif';
        case 'SWF':
            return '.SWF';
        default:
            return undefined;
    }
}